package com.lebang.service.cences;

import com.lebang.configuration.datasource.DataSource;
import com.lebang.domain.CencesEarnDay;
import com.lebang.domain.DownloadMemberRecord;
import com.lebang.domain.TaskRouse;
import com.lebang.example.CencesEarnDayExample;
import com.lebang.mapper.*;
import com.lebang.model.MyConfig;
import com.lebang.model.TaskRouseModel;
import com.lebang.model.Whether;
import com.lebang.model.cences.CencesMsg;
import com.lebang.model.cences.TotalCount;
import com.lebang.model.enums.buss.DownStatus;
import com.lebang.model.enums.buss.RewardTypeUscan;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.service.BaseService;
import com.lebang.service.mongodb.CencesMsgMongodb;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新手任务
 *
 * @Author hwq
 * @Date 2020-02-06
 */
@Service
@Slf4j
public class CencesEarnDayService extends BaseService<CencesEarnDay, Integer, CencesEarnDayExample> {
    @Autowired
    private CencesEarnDayMapper baseMapper;
    @Autowired
    private LbbMemberMapper lbbMemberMapper;
    @Autowired
    private TaskRouseMapper taskRouseMapper;
    @Autowired
    private MemberNewTradeMapper memberNewTradeMapper;

    @Autowired
    private DownloadMemberRecordMapper recordMapper;
    @Autowired
    private CencesMsgMongodb cencesMsgMongodb;


    public int deleteByTime(int time) {
        CencesEarnDayExample earnDayExample = new CencesEarnDayExample();
        earnDayExample.createCriteria().andTimeEqualTo(time).andAppIdEqualTo(MyConfig.getEnv());
        return baseMapper.deleteByExample(earnDayExample);
    }

    public void starDataInit(LocalDateTime end) {
        this.starDataInit(end, null);
    }

    public void starDataInit(LocalDateTime end, List<String> brand) {
        long starTime=System.currentTimeMillis();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDateTime star = end.minusDays(1);
        LocalDate starDate = star.toLocalDate();
        int time = Integer.parseInt(end.toLocalDate().minusDays(1).format(df));
        List<CencesEarnDay> cencesMasters = new ArrayList<>();
        if (brand == null) {
            brand = lbbMemberMapper.selectBrand();
        }
        List<String> sdkKey = taskRouseMapper.selectAllKey();
        List<DownloadMemberRecord> all=recordMapper.selectByTime(star,end);
        all.forEach(s->{s.setSdkKeyAppStoreIsNew(s.getSdkKey()+":"+s.getAppStore()+":"+s.getIsNewMember());});
        Map<String, List<DownloadMemberRecord>> listMap=all.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getSdkKeyAppStoreIsNew));
        //全部用户的
        List<String> finalBrand = brand;
        sdkKey.forEach(key -> {
            finalBrand.forEach(s -> {
                CencesEarnDay newVo = new CencesEarnDay(0, s, time, 1, key, 0,MyConfig.getEnv());
                CencesEarnDay oldVo = new CencesEarnDay(0, s, time, 0, key, 0,MyConfig.getEnv());
                CencesEarnDay allVo = new CencesEarnDay(0, s, time, 2, key, 1,MyConfig.getEnv());
                this.review(newVo,listMap,key+":"+s+":"+1);
                this.review(oldVo,listMap,key+":"+s+":"+0);
                sumBy(allVo, newVo);
                sumBy(allVo, oldVo);
                allVo.setFinishNum(allVo.getFinishNum()+newVo.getFinishNum());
                allVo.setFinishNum(allVo.getFinishNum()+oldVo.getFinishNum());
//                //baseMapper.selectAllData(s, star, end, key);
//                list.forEach(v -> {
//                    if (v.getCreateTime().toLocalDate().equals(starDate)) {
//                        //今天新增的用户
//                        this.record(v, newVo);
//                    } else {
//                        //老用户
//                        this.record(v, oldVo);
//                    }
//                    this.record(v, allVo);
//                });
                cencesMasters.add(newVo);
                cencesMasters.add(oldVo);
                baseMapper.insertEarnDay(allVo);
                baseMapper.insertEarnDay(newVo);
                baseMapper.insertEarnDay(oldVo);
            });
        });

        //总数计算
        CencesEarnDay item = new CencesEarnDay(0, "all", time, 2, "all", 1,MyConfig.getEnv());
        //新用户全部
        CencesEarnDay newAll = new CencesEarnDay(0, "all", time, 1, "all", 1,MyConfig.getEnv());
        //老用户全部
        CencesEarnDay oldAll = new CencesEarnDay(0, "all", time, 0, "all", 1,MyConfig.getEnv());

        cencesMasters.forEach(vo -> {
            sumBy(item, vo);
            if (vo.getCategory().equals(1)) {
                sumBy(newAll, vo);
            }
            if (vo.getCategory().equals(0)) {
                sumBy(oldAll, vo);
            }

        });
        Map<Integer, List<DownloadMemberRecord>> allMap=all.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getIsNewMember));
        this.checkFinish(allMap.get(1),newAll);
        this.checkFinish(allMap.get(0),oldAll);
        item.setFinishNum(newAll.getFinishNum()+oldAll.getFinishNum());

        baseMapper.insertEarnDay(item);
        baseMapper.insertEarnDay(newAll);
        baseMapper.insertEarnDay(oldAll);
        //数据源的全部
        all.forEach(s->{s.setSdkKeyAppStoreIsNew(s.getSdkKey()+":"+s.getIsNewMember());});
        Map<String, List<DownloadMemberRecord>> sdkKeyMap=all.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getSdkKeyAppStoreIsNew));
        sdkKey.forEach(key -> {
            CencesEarnDay sjy = new CencesEarnDay(0, "all", time, 2, key, 1,MyConfig.getEnv());
            //新用户全部
            CencesEarnDay newAlldata = new CencesEarnDay(0, "all", time, 1, key, 1,MyConfig.getEnv());
            //老用户全部
            CencesEarnDay oldAlldata = new CencesEarnDay(0, "all", time, 0, key, 1,MyConfig.getEnv());
            cencesMasters.forEach(vo -> {
                if (vo.getSdkKey().equals(key)) {
                    sumBy(sjy, vo);
                    if (vo.getCategory().equals(1)) {
                        sumBy(newAlldata, vo);
                    } else {
                        sumBy(oldAlldata, vo);
                    }
                }

            });


            this.checkFinish(sdkKeyMap.get(key+":"+1),newAlldata);
            this.checkFinish(sdkKeyMap.get(key+":"+0),oldAlldata);
            sjy.setFinishNum(newAlldata.getFinishNum()+oldAlldata.getFinishNum());

            baseMapper.insertEarnDay(sjy);
            baseMapper.insertEarnDay(oldAlldata);
            baseMapper.insertEarnDay(newAlldata);

        });
        //渠道的全部

        all.forEach(s->{s.setSdkKeyAppStoreIsNew(s.getAppStore()+":"+s.getIsNewMember());});
        Map<String, List<DownloadMemberRecord>> appStoreMap=all.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getSdkKeyAppStoreIsNew));
        brand.forEach(s -> {
            CencesEarnDay sjy = new CencesEarnDay(0, s, time, 2, "all", 1,MyConfig.getEnv());
            //新用户全部
            CencesEarnDay newAlldata = new CencesEarnDay(0, s, time, 1, "all", 1,MyConfig.getEnv());
            //老用户全部
            CencesEarnDay oldAlldata = new CencesEarnDay(0, s, time, 0, "all", 1,MyConfig.getEnv());
            cencesMasters.forEach(vo -> {
                if (vo.getBrand().equals(s)) {
                    sumBy(sjy, vo);
                    if (vo.getCategory().equals(1)) {
                        sumBy(newAlldata, vo);
                    } else {
                        sumBy(oldAlldata, vo);
                    }
                }

            });

            this.checkFinish(appStoreMap.get(s+":"+1),newAlldata);
            this.checkFinish(appStoreMap.get(s+":"+0),oldAlldata);
            sjy.setFinishNum(newAlldata.getFinishNum()+oldAlldata.getFinishNum());

            baseMapper.insertEarnDay(sjy);
            baseMapper.insertEarnDay(oldAlldata);
            baseMapper.insertEarnDay(newAlldata);
        });
        cencesMsgMongodb.save(new CencesMsg("每日必赚统计耗时",(System.currentTimeMillis()-starTime)));
    }

    private void review(CencesEarnDay newVo, Map<String, List<DownloadMemberRecord>> listMap, String s) {
        List<DownloadMemberRecord> list=listMap.get(s);
        if(list!=null){
            list.forEach(k->{
                this.record(k,newVo);
            });
            this.checkFinish(list,newVo);
        }
    }

    private void checkFinish(List<DownloadMemberRecord> list, CencesEarnDay newVo) {
        if(list==null){
            return;
        }
        Map<Integer,List<DownloadMemberRecord>> statusMap = list.stream().collect(Collectors.groupingBy(DownloadMemberRecord::getStatus));
        List<DownloadMemberRecord> successList = statusMap.get(DownStatus.SUCCESS.getIndex());
        if(successList!=null){
            List<DownloadMemberRecord> diffList= successList.stream().collect(
                    Collectors.collectingAndThen(
                            Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item -> item.getMemberId()))), ArrayList::new));
            if(diffList!=null){
                newVo.setFinishNum(diffList.size());
            }
        }
    }

    public CencesEarnDay sumData(Integer star, Integer end, String appStore, int category, int type, String sdkKey,String likeBrand,Integer appId) {
        return baseMapper.sumData(star, end, appStore, category, type, sdkKey,likeBrand,appId);
    }

    private void sumBy(CencesEarnDay item, CencesEarnDay vo) {
        item.setWaitCount(item.getWaitCount() + vo.getWaitCount());
        item.setSuccessCount(item.getSuccessCount() + vo.getSuccessCount());
        item.setFailCount(item.getFailCount() + vo.getFailCount());
        item.setDownCount(item.getDownCount() + vo.getDownCount());
        item.setLookCount(item.getLookCount() + vo.getLookCount());
        item.setDownRebate(item.getDownRebate().add(vo.getDownRebate()));
        item.setLookRebate(item.getLookRebate().add(vo.getLookRebate()));
    }



    private void record(DownloadMemberRecord v, CencesEarnDay newVo) {
        //待提交
        if (v.getStatus() == DownStatus.WAIT_PUSH.getIndex()) {
            newVo.setWaitCount(newVo.getWaitCount() + 1);
        }
        //成功
        if (v.getStatus() == DownStatus.SUCCESS.getIndex()) {
            newVo.setSuccessCount(newVo.getSuccessCount() + 1);
            //下载
            if (v.getType() == 1) {
                newVo.setDownCount(newVo.getDownCount() + 1);
            } else {
                //浏览
                newVo.setLookCount(newVo.getLookCount() + 1);
            }
        }
        //放弃
        if (v.getStatus() == DownStatus.RELSE.getIndex()) {
            newVo.setFailCount(newVo.getFailCount() + 1);
        }

        if (v.getType() == 1 && v.getStatus() == DownStatus.SUCCESS.getIndex()) {
            if (v.getRewardType().equals(RewardTypeUscan.Point.getIndex())) {
                newVo.setDownRebate(newVo.getDownRebate().add(new BigDecimal(v.getMoney()).divide(new BigDecimal(10000), 2, BigDecimal.ROUND_DOWN)));
            } else {
                newVo.setDownRebate(newVo.getDownRebate().add(new BigDecimal(v.getMoney()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)));
            }
        }
        if (v.getType() == 0 && v.getStatus() == DownStatus.SUCCESS.getIndex()) {
            if (v.getRewardType().equals(RewardTypeUscan.Point.getIndex())) {
                newVo.setLookRebate(newVo.getLookRebate().add(new BigDecimal(v.getMoney()).divide(new BigDecimal(10000), 2, BigDecimal.ROUND_DOWN)));
            } else {
                newVo.setLookRebate(newVo.getLookRebate().add(new BigDecimal(v.getMoney()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)));
            }
        }
    }

    public TotalCount selectData(LocalDateTime star, LocalDateTime end, String appStore,  int count,int between) {
        TotalCount totalCount=new TotalCount();
        int newCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star, end, appStore,  Whether.YES.getDbIndex(),count, TaskCategory.CSJ_ZXR.name());
        int oldCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star, end, appStore,  Whether.NO.getDbIndex(),count, TaskCategory.CSJ_ZXR.name());
        int allCount = newCount + oldCount;

        int betweennewCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star.minusDays(between), end.minusDays(between),appStore,  Whether.YES.getDbIndex(),count,  TaskCategory.CSJ_ZXR.name());
        int betweenoldCount = memberNewTradeMapper.countByCategoryGroupByMemberIdEarn(star.minusDays(between), end.minusDays(between), appStore, Whether.NO.getDbIndex(),count,  TaskCategory.CSJ_ZXR.name());
        int betweenallCount = betweennewCount + betweenoldCount;

        totalCount.setBetweenNewTotal(betweennewCount);
        totalCount.setBetweenOldTotal(betweenoldCount);
        totalCount.setBetweenTotal(betweenallCount);
        totalCount.setNewTotal(newCount);
        totalCount.setOldTotal(oldCount);
        totalCount.setTotal(allCount);
        totalCount.setCount(count);
        return totalCount;
    }

    public TaskRouseModel selectDatav2(LocalDateTime star, LocalDateTime end, String appStore, TaskRouse rouse, int between) {
        TaskRouseModel taskRouseModel=new TaskRouseModel();

        taskRouseModel.setSdkName(rouse.getTaskName());
        taskRouseModel.setSdkKey(rouse.getSdkKey());

        taskRouseModel.setAllTotal(recordMapper.selectByStatusAndSdkKey(star,end,appStore,rouse.getSdkKey(),null,null));
        taskRouseModel.setMoney(recordMapper.sumByStatusAndSdkKey(star,end,appStore,rouse.getSdkKey()));
        taskRouseModel.setNewTotal(recordMapper.selectByStatusAndSdkKey(star,end,appStore,rouse.getSdkKey(),1,Whether.YES.getDbIndex()));
        taskRouseModel.setOldTotal(recordMapper.selectByStatusAndSdkKey(star,end,appStore,rouse.getSdkKey(),1,Whether.NO.getDbIndex()));
        taskRouseModel.setSuccessTotal(taskRouseModel.getNewTotal()+taskRouseModel.getOldTotal());
        taskRouseModel.setNewCount(recordMapper.groupByMemberId(star,end,appStore,rouse.getSdkKey(),Whether.YES.getDbIndex()));
        taskRouseModel.setOldCount(recordMapper.groupByMemberId(star,end,appStore,rouse.getSdkKey(),Whether.YES.getDbIndex()));



        taskRouseModel.setOver_allTotal(recordMapper.selectByStatusAndSdkKey(star.minusDays(between),end.minusDays(between),appStore,rouse.getSdkKey(),null,null));
        taskRouseModel.setOver_money(recordMapper.sumByStatusAndSdkKey(star.minusDays(between),end.minusDays(between),appStore,rouse.getSdkKey()));
        taskRouseModel.setOver_newTotal(recordMapper.selectByStatusAndSdkKey(star.minusDays(between),end.minusDays(between),appStore,rouse.getSdkKey(),1,Whether.YES.getDbIndex()));
        taskRouseModel.setOver_oldTotal(recordMapper.selectByStatusAndSdkKey(star.minusDays(between),end.minusDays(between),appStore,rouse.getSdkKey(),1,Whether.NO.getDbIndex()));
        taskRouseModel.setOver_successTotal(taskRouseModel.getNewTotal()+taskRouseModel.getOldTotal());
        taskRouseModel.setOver_newCount(recordMapper.groupByMemberId(star.minusDays(between),end.minusDays(between),appStore,rouse.getSdkKey(),Whether.YES.getDbIndex()));
        taskRouseModel.setOver_oldCount(recordMapper.groupByMemberId(star.minusDays(between),end.minusDays(between),appStore,rouse.getSdkKey(),Whether.YES.getDbIndex()));
         return taskRouseModel;
    }

    @DataSource("commonDB")
    public long countEarnDay(CencesEarnDayExample example) {
        return baseMapper.countByExample(example);
    }

    @DataSource("commonDB")
    public List<CencesEarnDay> selectEarnDay(CencesEarnDayExample example) {
        return baseMapper.selectByExample(example);
    }
}
